<?php

/**
 * RabbitCMS
 * 
 * LICENSE
 *
 * This source file is subject to the GNU GENERAL PUBLIC LICENSE Version 2 
 * that is bundled with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://www.gnu.org/licenses/gpl-2.0.txt
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@rabbitcms.com so we can send you a copy immediately.
 * 
 * @copyright	Copyright (c) 2009-2010 TIG Corporation (http://www.tig.vn)
 * @license		http://www.gnu.org/licenses/gpl-2.0.txt GNU GENERAL PUBLIC LICENSE Version 2
 * @version 	$Id: Category.php 5341 2010-09-07 09:04:47Z huuphuoc $
 * @since		2.0.5
 */
class Category_Models_Category extends Rabbit_Db_Table_Abstract implements Category_Models_Interfaces_Category {

    protected $_name = 'category';

    public function convert($entity){
        return new Category_Models_Entities_Category($entity);
    }
    public function getById($id) {
        $row = $this->getAdapter()
                        ->select()
                        ->from(array('m' => $this->_name))
                        ->where('m.id = ?', $id)
                        ->limit(1)
                        ->query()
                        ->fetch();
        return (null == $row) ? null : new Category_Models_Entities_Category($row);
    }

    public function getSubCategories($categoryId) {
        $rs = $this->_conn
                        ->select()
                        ->from(array('c' => $this->_prefix . 'category'))
                        /**
                         * @since 2.0.8
                         */
                        ->where('c.language = ?', $this->_lang)
                        ->where('c.parent_id = ?', $categoryId)
                        ->query()
                        ->fetchAll();
        return new Rabbit_Model_RecordSet($rs, $this);
    }

    public function add($category) {
        try {
            $parentId = $category->parent_id;
            $db = $this->getAdapter();
            if ($parentId != 0) {
                $sql = $db->select()->from($this->_name, array('rht'))->where('id = ?', $parentId);
                $right = $db->query($sql)->fetchColumn(0);
            } else {
                $sql = $db->select()->from($this->_name, array('rht' => 'MAX(rht)'));
                $right = $db->query($sql)->fetchColumn(0);
            }
            if ($right != null) {
                //update tree
                $data = array(
                    'lft' => new Zend_Db_Expr('IF (lft >= ' . $db->quote($right) . ', lft + 2, lft)'),
                    'rht' => new Zend_Db_Expr('IF (rht >= ' . $db->quote($right) . ', rht + 2, rht)')
                );
                $this->update($data, null);
                $category->lft = $right;
                $category->rht = $right + 1;
                $category = $this->createRow($category->getProperties());
                $category->save();

                if ($category->id) {
                    return $category->id;
                } else {
                    return false;
                }
            }
        } catch (Exception $ex) {
            echo $ex->getMessage();
            return false;
        }
    }

    public function edit($category) {
        try {
            if ($this->update($params->getProperties(), 'id = ' . $params->id)) {
                return true;
            } else {
                return false;
            }
        } catch (Exception $ex) {
            echo $ex->getMessage();
            return false;
        }
    }

    public function delete($category) {
        try {
            parent::delete('id =' . $category->id);
            $this->update(
                    array(
                        'lft' => new Zend_Db_Expr('lft - 1'),
                        'rht' => new Zend_Db_Expr('rht - 1'),
                    ),
                    array(
                        'lft >= ?' => $category->lft,
                        'lft <= ?' => $category->rht,
            ));

            $this->update(
                    array(
                        'rht' => new Zend_Db_Expr('rht - 2'),
                    ),
                    array(
                        'rht > ?' => $category->rht,
            ));

            $this->update(
                    array(
                        'lft' => new Zend_Db_Expr('lft - 2'),
                    ),
                    array(
                        'lft > ?' => $category->rht,
            ));
            return true;
        } catch (Exception $ex) {
            echo $ex->getMessage();
            return false;
        }
    }

    public function getTree($module_name = null) {
        try {
            $root = $this->find(1)->current();
            $select = $this->getAdapter()
                            ->select()
                            ->from($this->_name, '*')
                            ->where('lft BETWEEN ' . $root->lft . ' AND ' . $root->rht)
                            ->where('id <> 1')->order('lft ASC')
                            ->where('language = ?', $this->_lang);
            if($module_name) $select->where ('module_name = ?', $module_name);
            $results = $select->query()->fetchAll();
            return ($results != null) ? new Tomato_Model_RecordSet($results, $this) : null;
        } catch (Exception $ex) {
            echo $ex->getMessage();
            return null;
        }
    }

    public function getParents($categoryId) {
        $rs = $this->_conn
                        ->select()
                        ->from(array('node' => $this->_prefix . 'category'), array())
                        ->from(array('parent' => $this->_prefix . 'category'))
                        ->where('node.left_id BETWEEN parent.left_id AND parent.right_id')
                        ->where('node.id = ?', $categoryId)
                        ->order('parent.left_id')
                        ->query()
                        ->fetchAll();
        return new Rabbit_Model_RecordSet($rs, $this);
    }

    public function getParentId($categoryId) {
        $rs = $this->_conn
                        ->select()
                        ->from(array('c1' => $this->_prefix . 'category'), array())
                        ->joinInner(array('c2' => $this->_prefix . 'category'), 'c1.left_id BETWEEN c2.left_id AND c2.right_id', array('category_id'))
                        ->where('c1.category_id = ?', $categoryId)
                        ->where('c2.category_id <> ?', $categoryId)
                        ->query()
                        ->fetchAll();
        return (count($rs) == 0) ? $categoryId : $rs[0]->category_id;
    }

    public function updateOrder($category) {
        $this->_conn->update($this->_prefix . 'category',
                array(
                    'parent_id' => $category->parent_id,
                    'left_id' => $category->left_id,
                    'right_id' => $category->right_id,
                ),
                array(
                    'category_id = ?' => $category->category_id,
        ));
    }

    /* ========== For translation =========================================== */

    public function getTranslations($item) {
        $rs = $this->getAdapter()
                        ->select()
                        ->from(array('c' => $this->_prefix . 'category'))
                        ->joinInner(array('tr' => $this->_prefix . 'core_translation'),
                                'tr.item_class = ?
						AND (tr.item_id = ? OR tr.source_item_id = ?)
						AND (tr.item_id = c.id OR tr.source_item_id = c.id)',
                                array('tr.source_item_id'))
                        ->group('c.id')
                        ->bind(array(
                            'Category_Models_Entities_Category',
                            $item->id,
                            $item->id,
                        ))
                        ->query()
                        ->fetchAll();
        return (null == $rs) ? null : new Tomato_Model_RecordSet($rs, $this);
    }

    public function getTranslatable($lang){
        $db = $this->getAdapter();
        $root = $this->find(1)->current();
        $sql = 'SELECT c.*, (tr.item_id IS NULL) AS translatable
				FROM
				(
					SELECT id, name, lft, rht FROM ' . $this->_name. '
                              WHERE  (lft BETWEEN ' . $root->lft . ' AND ' . $root->rht . ')
                              AND (id <> 1) AND language = ?
                              ORDER BY lft ASC    
				) AS c
				LEFT JOIN ' . $this->_prefix . 'core_translation AS tr
					ON tr.source_item_id = c.id
					AND tr.item_class = ?
					AND tr.source_language = ?
					AND tr.language = ?';

        $rs = $db->query($sql,
                                array(
                                    $this->_lang,
                                    'Category_Models_Enities_Category',
                                    $this->_lang, $lang
                        ))
                        ->fetchAll();
        return new Tomato_Model_RecordSet($rs, $this);
    }

    public function getSource($category) {
        $row = $this->getAdapter()
                        ->select()
                        ->from(array('c' => $this->_prefix . 'category'))
                        ->joinInner(array('tr' => $this->_prefix . 'core_translation'), 'c.id = tr.source_item_id', array())
                        ->where('tr.item_id = ?', $category->id)
                        ->where('tr.item_class = ?', 'Category_Models_Entities_Category')
                        ->limit(1)
                        ->query()
                        ->fetch();
        return (null == $row) ? null : new Category_Models_Entities_Category($row);
    }

    /**
     * Added by tronghm
     */
    public function exist($name){
        $category = $this->fetchRow($this->select()->where('name = ? ', $name));
        return ($category) ? true : false;
    }

}
